package com.yhc.server.service.impl;

import com.yhc.server.consts.RedisPrefixKey;
import com.yhc.server.consts.SystemValue;
import com.yhc.server.exception.SBFServiceException;
import com.yhc.server.plugin.RedisService;
import com.yhc.server.plugin.SendMessageService;
import com.yhc.server.service.ISmsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SmsServiceImpl implements ISmsService {

    @Autowired
    RedisService redisService;
    @Autowired
    SendMessageService sendMsgService;

    @Override
    public void send(String mobile, String code) {
        // 短信校验限制，一分钟内只能发送一次
        String smsCodeFlagKey = String.format(RedisPrefixKey.SMS_CODE_SEND_FLAG, mobile);
        if (redisService.exists(smsCodeFlagKey)) {
            throw new SBFServiceException("一分钟内只能发送一次短信");
        }
        redisService.set(smsCodeFlagKey, "1", 60);

        // TODO 此处建议加上每天发送次数的限制

        // 发送验证码
        sendMsgService.sendSms(mobile, code);  // 调用短信服务进行验证码发送

        // 缓存验证码
        String smsCodeKey = String.format(RedisPrefixKey.SMS_CODE_LOGIN, mobile);
        redisService.set(smsCodeKey, code, 60 * 5);

        // 清空输入错误次数
        redisService.delete(String.format(RedisPrefixKey.SMS_CODE_LOGIN_ERROR_NUMBER, mobile));
    }

    @Override
    public void codeVerify(String mobile, String validCode) {
        // 校验短信验证码错误次数
        String smsCodeErrorNumberKey = String.format(RedisPrefixKey.SMS_CODE_LOGIN_ERROR_NUMBER, mobile);
        String smsCodeErrorNumber = redisService.get(smsCodeErrorNumberKey);
        int errorNum = 0;
        if (StringUtils.isNotBlank(smsCodeErrorNumber)) {
            errorNum = Integer.parseInt(smsCodeErrorNumber);
            if (errorNum >= SystemValue.LOGIN_MSG_CODE_ERROR_LIMIT) {
                throw new SBFServiceException("失败次数过多，请重新发送短信。");
            }
        }

        // 校验短信验证码
        String cacheSmsCodeKey = String.format(RedisPrefixKey.SMS_CODE_LOGIN, mobile);
        String cacheSmsCode = redisService.get(cacheSmsCodeKey);
        if (StringUtils.isBlank(cacheSmsCode)) {
            throw new SBFServiceException("验证码已失效，请重新发送短信。");
        } else {
            if (!StringUtils.equals(cacheSmsCode, validCode)) {
                errorNum += 1;
                redisService.set(smsCodeErrorNumberKey, errorNum);
                int specificNumber = SystemValue.LOGIN_MSG_CODE_ERROR_LIMIT - errorNum;
                throw new SBFServiceException("验证码错误，您还有%s次重试机会。", specificNumber);
            }
        }

        // 清理验证码
        redisService.delete(cacheSmsCodeKey);
        redisService.delete(smsCodeErrorNumberKey);
    }
}
